<template>
  <BasicModal
    v-bind="$attrs"
    @register="registerModal"
    title="生成代码"
    :width="800"
    @ok="handleSuccess"
  >
    <BasicForm @register="registerForm" />
  </BasicModal>
</template>
<script lang="ts" setup>
  import { ref, computed, reactive } from 'vue';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { BasicForm, useForm, FormSchema, FormProps } from '/@/components/Form/index';
  import { getDatabaselinkMultiTableColumns } from '/@/api/system/databaselink';
  import { getAuthList } from '/@/api/system/authorize';
  import { useUserStore } from '/@/store/modules/user';
  import { GeneratorModel } from '/@/api/system/generator/model';
  import { ComponentOptionModel } from '/@/model/generator/codeGenerator';
  import { FormEventColumnConfig } from '/@/model/generator/formEventConfig';
  import { debounce, random, cloneDeep } from 'lodash-es';
  import { buildUUID } from '/@/utils/uuid';
  import { JavaTypeConvertTsType, buildOption } from '/@/utils/helper/designHelper';
  import { buildCode } from '/@/utils/helper/generatorHelper';

  import { useI18n } from '/@/hooks/web/useI18n';

  const { t } = useI18n();
  const userStore = useUserStore();

  const dataAuthHelpMessage = `
    1.启用数据权限会判断主表是否包含RuleUserlD字段如果存在，则不进行表结构修改，如果不存在，则会对主表进行字段添加。
    2.RuleUserlD主要用来控制每一条记录的权限所属人新增时，默认将当前登录认作为权限所属人。
    3.在表单设计中会添加“批量设置权限所属人”功能启用后，拥有该按钮权限的人员可以设置每一条记录的权限所属人。
      `;

  const dataAuthPlaceholder = computed(() => {
    return generatorConfig!.outputConfig!.isDataAuth
      ? t('请选择已有通用数据权限')
      : t('请先启用数据权限');
  });

  const inputComponentInfo: ComponentOptionModel = {
    label: '单行文本',
    typeName: '单行文本',
    type: 'input',
    options: {
      width: '100%',
      span: '',
      defaultValue: '',
      placeholder: '请输入单行文本',
      maxlength: '',
      prefix: '',
      suffix: '',
      addonBefore: '',
      addonAfter: '',
      disabled: false,
      allowClear: false,
      showLabel: true,
      required: false,
      rules: [],
      events: {},
    },
    key: '',
    rules: [],
    isSubFormChild: false,
    isSingleFormChild: false,
    bindTable: '',
    bindField: '',
  };

  const numberComponentInfo: ComponentOptionModel = {
    label: '计数组件',
    typeName: '计数组件',
    type: 'number',
    options: {
      width: '100%',
      span: '',
      defaultValue: 0,
      min: 0,
      max: 100,
      step: 1,
      maxlength: '',
      disabled: false,
      showLabel: true,
      controls: true,
      required: false,
      subTotal: false,
      rules: [],
      events: {},
    },
    key: '',
    rules: [],
    isSubFormChild: false,
    isSingleFormChild: false,
    bindTable: '',
    bindField: '',
  };

  const timeComponentInfo: ComponentOptionModel = {
    label: '时间选择',
    typeName: '时间选择',
    type: 'time',
    options: {
      span: '',
      defaultValue: '',
      width: '100%',
      placeholder: '请选择时间选择',
      format: 'HH:mm:ss',
      showLabel: true,
      allowClear: true,
      disabled: false,
      required: false,
      rules: [],
      events: {},
    },
    key: '',
    rules: [],
    isSubFormChild: false,
    isSingleFormChild: false,
    bindTable: '',
    bindField: '',
  };

  const dateComponentInfo: ComponentOptionModel = {
    label: '日期选择',
    typeName: '日期选择',
    type: 'date',
    options: {
      span: '',
      defaultValue: '',
      width: '100%',
      placeholder: '请选择日期选择',
      format: 'YYYY-MM-DD HH:mm:ss',
      showLabel: true,
      allowClear: true,
      disabled: false,
      required: false,
      rules: [],
      events: {},
    },
    key: '',
    rules: [],
    isSubFormChild: false,
    isSingleFormChild: false,
    bindTable: '',
    bindField: '',
  };
  const outputValue = ref('');
  const columnsInfo = ref<any>({});
  const codeList = ref<GeneratorModel[]>([]);

  const emit = defineEmits(['success']);

  let generatorConfig = reactive<GeneratorModel>({
    name: '',
    categoryId: '1697809616871182337',
    databaseId: null, //数据库id
    listConfig: {
      isLeftMenu: false,
      queryConfigs: [],
      leftMenuConfig: {
        datasourceType: 'static',
        listFieldName: undefined,
        apiConfig: {},
        dictionaryItemId: undefined,
        menuName: '',
        parentIcon: '',
        childIcon: '',
        staticData: [],
      },
      columnConfigs: [],
      buttonConfigs: [
        {
          isUse: true,
          name: '刷新',
          code: 'refresh',
          icon: 'ant-design:reload-outlined',
          isDefault: true,
        },
        {
          isUse: true,
          name: '查看',
          code: 'view',
          icon: 'ant-design:eye-outlined',
          isDefault: true,
        },
        {
          isUse: true,
          name: '新增',
          code: 'add',
          icon: 'ant-design:plus-outlined',
          isDefault: true,
        },
        {
          isUse: true,
          name: '编辑',
          code: 'edit',
          icon: 'ant-design:form-outlined',
          isDefault: true,
        },
        {
          isUse: true,
          name: '删除',
          code: 'delete',
          icon: 'ant-design:delete-outlined',
          isDefault: true,
        },
      ],
      defaultOrder: true,
      isPage: true,
    },
    tableConfigs: [],
    formJson: {
      list: [],
      config: {
        formType: 'modal',
        size: 'default',
        layout: 'horizontal',
        labelAlign: 'right',
        labelCol: {
          span: 3,
          offset: 0,
        },
        formWidth: 800,
      },
      hiddenComponent: [],
    },
    outputConfig: {
      creator: userStore.getUserInfo.name,
      isMenu: true,
      type: 0,
    },
    formEventConfig: {} as FormEventColumnConfig,
    frontCode: {
      listCode: '',
      formCode: '',
      apiCode: '',
      modelCode: '',
      configJsonCode: '',
    },
  });
  const schemas: FormSchema[] = [
    {
      field: 'className',
      label: t('功能名称'),
      component: 'Input',
      rules: [
        {
          required: true,
          validator: (_, value) => {
            if (value === '') {
              return Promise.reject('请输入功能名称');
            } else if (!/^[a-zA-Z][a-zA-Z0-9]*$/.test(value)) {
              return Promise.reject(t('功能名称只能是数字和字母组成，必须以英文字母开头'));
            } else {
              return Promise.resolve();
            }
          },
          trigger: 'blur',
        },
      ],
      colProps: { span: 24 },
      componentProps: {
        placeholder: '请填写功能名称',
      },
    },
    {
      field: 'comment',
      label: t('功能描述'),
      required: true,
      component: 'Input',
      colProps: { span: 24 },
      componentProps: {
        placeholder: '请填写功能描述',
      },
    },
    {
      field: 'outputArea',
      label: t('功能模块'),
      component: 'DicSelect',
      required: true,
      componentProps: {
        placeholder: t('请选择功能模块'),
        itemId: '1419276800524423333',
        getPopupContainer: () => document.body,
        onChange: debounce((_, obj) => {
          if (obj) {
            outputValue.value = obj.value;
          }
        }, 100),
      },
      colProps: { span: 24 },
    },
    {
      field: 'remarks',
      label: t('备注'),
      component: 'Input',
      colProps: { span: 24 },
      componentProps: {
        placeholder: t('请填写备注'),
      },
    },
    {
      field: 'isDataAuth',
      label: t('数据权限'),
      component: 'Switch',
      colProps: { span: 24 },
      helpMessage: dataAuthHelpMessage,
      helpComponentProps: { maxWidth: '400px' },
      componentProps: {
        checkedValue: true,
        unCheckedValue: false,
      },
    },
    {
      field: 'dataAuthList',
      label: t('权限选择'),
      component: 'ApiSelect',
      colProps: { span: 24 },
      componentProps: {
        mode: 'multiple',
        placeholder: dataAuthPlaceholder,
        api: getAuthList,
        labelField: 'name',
        valueField: 'id',
        getPopupContainer: () => document.body,
      },
      dynamicDisabled: ({ values }) => {
        return !values.isDataAuth;
      },
    },
  ];
  const [registerForm, { validate }] = useForm({
    labelWidth: 100,
    schemas: schemas,
    showActionButtonGroup: false,
    actionColOptions: {
      span: 23,
    },
  });
  const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
    setModalProps({
      confirmLoading: false,
      destroyOnClose: true,
    });

    columnsInfo.value = await getDatabaselinkMultiTableColumns({
      id: data.databaseId,
      tableNames: data.tableName.toString(),
    });
    for (let key in columnsInfo.value) {
      const generatorConfigInfo = cloneDeep(generatorConfig);
      if (!generatorConfigInfo.databaseId) generatorConfigInfo.databaseId = data.databaseId;

      const col = columnsInfo.value[key].find((x) => x.primaryKey);
      generatorConfigInfo.tableConfigs = [
        {
          isMain: true,
          order: 1,
          pkField: col.column,
          pkType: col.dataType,
          tableName: key,
        },
      ];
      generatorConfigInfo.name = key;
      columnsInfo.value[key].forEach((item) => {
        let info;
        switch (item.dataType) {
          case 'LocalTime':
            info = timeComponentInfo;
            break;
          case 'LocalDateTime':
            info = dateComponentInfo;
            break;
          case 'Integer':
            info = numberComponentInfo;
            break;
          default:
            info = inputComponentInfo;
            break;
        }

        const componentInfo = cloneDeep(info);
        componentInfo.key = buildUUID().replaceAll('-', '');
        componentInfo.bindTable = key;
        componentInfo.bindField = item.column;
        componentInfo.label = item.column;
        generatorConfigInfo.formJson.list.push(componentInfo);

        generatorConfigInfo.listConfig.queryConfigs.push({
          fieldName: item.column,
          isDate: ['LocalTime', 'LocalDateTime'].includes(item.dataType),
          width: 8,
        });
        console.log('queryConfigsqueryConfigs', generatorConfigInfo.listConfig.queryConfigs);
        generatorConfigInfo.listConfig.columnConfigs.push({
          key: componentInfo.key,
          autoWidth: true,
          columnName: item.column,
          componentType: 'input',
          isNumber: false,
          isTotal: false,
          label: item.column,
        });
      });

      const fieldsInfo = columnsInfo.value[key].map((field) => {
        return {
          name: field.column,
          length: field.dataLength,
          type: JavaTypeConvertTsType(field.dataType),
          isPk: field.primaryKey,
          isNullable: field.nullable,
        };
      });
      const tableInfo = [
        {
          name: key,
          fields: fieldsInfo,
          isMain: true,
        },
      ];
      generatorConfigInfo.frontCode = buildCode(
        generatorConfigInfo,
        tableInfo,
        buildOption(generatorConfigInfo.formJson) as FormProps,
      );

      codeList.value.push(generatorConfigInfo);
    }
  });

  const handleSuccess = async () => {
    const data = await validate();
    codeList.value.map(async (item) => {
      item.outputConfig = { ...item.outputConfig, ...data };
      item.outputConfig.className = item.outputConfig.className! + random(1000, 9999);
      item.outputConfig.outputValue = outputValue.value;

      const fieldsInfo = columnsInfo.value[item.name!].map((field) => {
        return {
          name: field.column,
          length: field.dataLength,
          type: JavaTypeConvertTsType(field.dataType),
          isPk: field.primaryKey,
          isNullable: field.nullable,
        };
      });
      const tableInfo = [
        {
          name: item.name!,
          fields: fieldsInfo,
          isMain: true,
        },
      ];
      item.frontCode = buildCode(item, tableInfo, buildOption(item.formJson) as FormProps);

      closeModal();
    });
    emit('success', codeList.value);
  };
</script>
